package com.kaifamiao.wendao.dao;

import com.kaifamiao.wendao.entity.Customer;
import com.kaifamiao.wendao.entity.Explain;
import com.kaifamiao.wendao.entity.Topic;
import org.apache.commons.dbutils.ResultSetHandler;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class ExplainDao extends BaseDao<Explain,Long> {

    private TopicDao topicDao=new TopicDao();
    private CustomerDao customerDao=new CustomerDao();

    private static final String INSERT_ONE="INSERT INTO t_explains (id,customer_id,publish_time,publish_address,topic_id,content,praise,despise) VALUES(?,?,?,?,?,?,?,?)";

    private static final String UPDATE_ONE="UPDATE t_explains SET publish_time=?,publish_address=?,content=?,praise=?,despise=? ,customer_id=? WHERE id=?";
    private static final String DELETE_ONE="DELETE FROM t_explains WHERE id=?";
    private static final String DELETE_ALL="DELETE FROM t_explains WHERE topic_id=?";
    private static final String SELECT_ALL="SELECT * FROM t_explains WHERE topic_id = ? ORDER BY id";
    private static final String SELECT_ONE_BY_ID="SELECT  * FROM  t_explains WHERE  id=?";
    private static final String FETCH_BY_TOPIC_ID = "SELECT id, content, publish_time, praise, despise, customer_id FROM t_explains WHERE topic_id = ?";
    private static final String FETCH_BY_CUSTOMER_ID = "SELECT id, content, publish_time, praise, despise, customer_id FROM t_explains WHERE customer_id = ?";

    private Explain wrap(ResultSet resultSet) throws SQLException{
        Explain explain=new Explain();
        explain.setId(resultSet.getLong("id"));
        explain.setContent(resultSet.getString("content"));
        explain.setPraise(resultSet.getInt("praise"));
        explain.setDespise(resultSet.getInt("despise"));
        Long cid=resultSet.getLong("customer_id");
        Customer author=customerDao.find(cid);
        explain.setAuthor(author);
        java.sql.Timestamp timestamp= resultSet.getTimestamp("publish_time");
        LocalDateTime dateTime=timestamp==null?null:timestamp.toLocalDateTime();
        explain.setPublishTime(dateTime);
        explain.setPublishAddress(resultSet.getString("publish_address"));
        Long tid=resultSet.getLong("topic_id");
        Topic topic= topicDao.find(tid);
        explain.setTopic(topic);
        return explain;
    }
    private ResultSetHandler<List<Explain>> listHandler = rs -> {
        List<Explain> explains = new ArrayList<>();
        while(rs.next()){
            Explain e = new Explain();
            e.setId(rs.getLong("id"));
            e.setContent(rs.getString("content"));
            java.sql.Timestamp time = rs.getTimestamp("publish_time");
            LocalDateTime publishTime = time != null ? time.toLocalDateTime() : null ;
            e.setPublishTime(publishTime);
            e.setPraise(rs.getInt("praise"));
            e.setDespise(rs.getInt("despise"));
            long cid = rs.getLong("customer_id");
            Customer author = new Customer();
            author.setId(cid);
            e.setAuthor(author);
            explains.add(e);
        }
        return explains;
    };

    @Override
    public boolean save(Explain explain) {
        LocalDateTime dateTime=explain.getPublishTime();
        java.sql.Timestamp timestamp=dateTime==null?null:java.sql.Timestamp.valueOf(dateTime);
        Object[]params={explain.getId(),explain.getAuthor().getId(),timestamp,explain.getPublishAddress(),explain.getTopic().getId(),explain.getContent(),explain.getPraise(),explain.getDespise()};
        try{
            return runner.update(INSERT_ONE,params)==1;
        }catch (SQLException e){
            throw new RuntimeException("保存评论失败",e);
        }
    }

    @Override
    public boolean update(Explain explain) {
        LocalDateTime dateTime=explain.getPublishTime();
        java.sql.Timestamp timestamp=dateTime==null?null:java.sql.Timestamp.valueOf(dateTime);
        Object[]params={timestamp,explain.getPublishAddress(),explain.getContent(),explain.getPraise(),explain.getDespise(),explain.getAuthor().getId(),explain.getId()};
        try{
            return runner.update(UPDATE_ONE,params)==1;
        }catch (SQLException e){
            throw new RuntimeException("更新评论失败",e);
        }
    }

    @Override
    public boolean remove(Long id) {
        try{
            return runner.update(DELETE_ONE,id)==1;
        }catch (SQLException e){
            throw new RuntimeException("删除评论失败",e);
        }
    }

    public boolean removeAll(Long id) {
        try{
            return runner.update(DELETE_ALL,id)==1;
        }catch (SQLException e){
            throw new RuntimeException("删除评论失败",e);
        }
    }

    @Override
    public List<Explain> findAll() {
        ResultSetHandler<List<Explain>> rsHandler=resultSet -> {
            List<Explain> list=new ArrayList<>();
            while (resultSet.next()){
                Explain explain= wrap(resultSet);
                list.add(explain);
            }
            return list;
        };
        try{
            return runner.query(SELECT_ALL,rsHandler);
        }catch (SQLException e){
            throw new RuntimeException("查询所有评论失败",e);
        }
    }

    public List<Explain> findAll(Long tid) {
        ResultSetHandler<List<Explain>> rsHandler=resultSet -> {
            List<Explain> list=new ArrayList<>();
            while (resultSet.next()){
                Explain explain= wrap(resultSet);
                list.add(explain);
            }
            return list;
        };
        try{
            return runner.query(SELECT_ALL,rsHandler,tid);
        }catch (SQLException e){
            throw new RuntimeException("查询所有评论失败",e);
        }
    }

    public List<Explain> loadByCustomerID(Long Cid) {
        try {
            return runner.query(FETCH_BY_CUSTOMER_ID, listHandler, Cid);
        }catch (SQLException cause){
            throw new RuntimeException("查询失败",cause);
        }
    }

    @Override
    public Explain find(Long id) {
        ResultSetHandler<Explain> rsHandler= resultSet -> {
            if(resultSet.next()){
                Explain explain=wrap(resultSet);
                return explain;
            }
            return null;
        };
        try{
            return runner.query(SELECT_ONE_BY_ID,rsHandler,id);
        }catch (SQLException e){
            throw new RuntimeException("查询单个评论失败",e);
        }
    }

    public List<Explain> findByTopicId(Long topicId) {
        try {
            return runner.query(FETCH_BY_TOPIC_ID, listHandler, topicId);
        }catch (SQLException cause){
            throw new RuntimeException("查询失败",cause);
        }
    }
}
